/*
 * @Descripttion: 全局异常处理，可在配置文件中设置是否启用
 * @version: 
 * @Author: turingchang
 * @Date: 2020-08-22 16:18:21
 * @LastEditors: turingchang
 * @LastEditTime: 2020-08-28 13:20:04
 */

const { dateToTimeStamp } = require("../common/utils/time");

module.exports = (options) => {
    return async function errorHandler(ctx, next) {
        var start =Date.now();
        ctx.start_time =start;
        try { 
            //console.log(0,ctx.status);
            await next();
            //console.log(1,ctx.status);
            //await dealStatus(ctx, next); 
            await deal(ctx, next,null);          
        } catch (err) {
            await deal(ctx, next,err);
        }
    };

    async function deal(ctx, next,err) {
        ctx.end_time =Date.now();
        ctx.interval =ctx.end_time-ctx.start_time;
        var error =''; 
        if(!ctx.app.utils.validator.isNull(err)){            
            error =err.message;
        }         
        var res =false;
        //var ss =` ------------------------------------>>>>>>>>> ${ctx.app.name} <<<<<<<<<------------------------------------ \n`;
        var ss =ctx.app.config.console.request.style;
        var s ='';
        if(options.enable ===true){
            //ctx.app.emit('error', error, ctx); //记录任何有异常的记录，输出日志以及输出到控制台            
            switch(ctx.status){
                case 403:                    
                    ctx.app.emit('error', error, ctx);
                    ctx.requestLogger.error(ctx.app.enums.response_code_enum.forbid.msg);
                    s =ss+ `${new Date().toLocaleString()} [${ctx.ip}] [${ctx.method} ${ctx.url}] : ${ctx.app.enums.response_code_enum.forbid.msg} \n`+ss;
                    console.log(s.bgMagenta);
                    return ctx.outError(error,null,ctx.app.enums.response_code_enum.forbid);  
                    break;
                case 404:
                    ctx.app.emit('error', error, ctx);
                    //注意，这里服务器报错后仍然为404，而不是500，手动处理
                    if(ctx.app.utils.validator.isNull(err)){                    
                        ctx.requestLogger.error(ctx.app.enums.response_code_enum.not_found.msg);
                        //s =ss+`${ctx.request_url} -> `+ctx.app.enums.response_code_enum.not_found.msg+'\n'+ss;
                        s =ss+ `${new Date().toLocaleString()} [${ctx.ip}] [${ctx.method} ${ctx.url}] : ${ctx.app.enums.response_code_enum.not_found.msg} \n`+ss;
                        console.log(s.bgRed);
                        return ctx.outError(error,null,ctx.app.enums.response_code_enum.not_found);  
                    } else{
                        ctx.requestLogger.error(JSON.stringify(err.stack));
                        //s =ss+`${ctx.request_url} -> `+err.stack+'\n'+ss;
                        s =ss+ `${new Date().toLocaleString()} [${ctx.ip}] [${ctx.method} ${ctx.url}] : ${err.stack} \n`+ss;
                        console.log(s.bgRed);
                        return ctx.outError(error,null,ctx.app.enums.response_code_enum.server_error);  
                    }   
                    break;
                case 500:
                    ctx.app.emit('error', error, ctx);
                    if(ctx.app.utils.validator.isNull(err)){
                        ctx.requestLogger.error(ctx.app.enums.response_code_enum.server_error.msg);
                        //s =ss+`${ctx.request_url} -> `+ctx.app.enums.response_code_enum.server_error.msg+'\n'+ss;
                        s =ss+ `${new Date().toLocaleString()} [${ctx.ip}] [${ctx.method} ${ctx.url}] : ${ctx.app.enums.response_code_enum.server_error.msg} \n`+ss;
                        console.log(s.bgRed);
                    }else{
                        ctx.requestLogger.error(JSON.stringify(err.stack));
                        //s =ss+`${ctx.request_url} -> `+err.stack+'\n'+ss;
                        s =ss+ `${new Date().toLocaleString()} [${ctx.ip}] [${ctx.method} ${ctx.url}] : ${err.stack} \n`+ss;
                        console.log((err.stack).bgRed);
                    }                    
                    return ctx.outError(error,null,ctx.app.enums.response_code_enum.server_error);  
                    break;
                default:
                    ctx.requestLogger.info();
                    s =ss+ `${new Date().toLocaleString()} [${ctx.ip}] [${ctx.method} ${ctx.url}] : ${ctx.response.status}  ${ctx.response.message} \n`+ss;
                    console.log(s.bgGreen);
                    break;
            }               
        }
        
    }

    async function dealStatus(ctx, next,err) {
        var error;  
        var res =false;
        if(options.enable ===true){
            switch(ctx.status){
                case 403:
                    return ctx.outError(error,null,ctx.app.enums.response_code_enum.forbid);  
                    break;
                case 404:
                    return ctx.outError(error,null,ctx.app.enums.response_code_enum.not_found);  
                    break;
                case 500:
                    return ctx.outError(error,null,ctx.app.enums.response_code_enum.server_error);  
                    break;
                default: res =true;break;
            }            
        }else{
            res =true;
        }
        return res;
        
    }    


};